package com.yuma.tingshu.common.config.redis;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import java.util.concurrent.ExecutorService;

@Configuration("commonThreadPoolConfigClass")
public class ThreadPoolConfig {

    @Value("${thread-pool.corePoolSize}")
    private Integer corePoolSize;
    @Value("${thread-pool.maximumPoolSize}")
    private Integer maximumPoolSize;
    @Value("${thread-pool.keepAliveTime}")
    private Integer keepAliveTime;
    @Value("${thread-pool.workQueueSize}")
    private Integer workQueueSize;

    @Bean("commonThreadPoolConfig")
    public ExecutorService executorService() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

        // 设置核心参数
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maximumPoolSize);
        executor.setKeepAliveSeconds(keepAliveTime);
        executor.setQueueCapacity(workQueueSize);

        // 设置线程名前缀，便于调试
        executor.setThreadNamePrefix("ContextAware-");

        // ✅✅✅ 关键修复：使用 getRequestAttributes() + 判空，避免启动时报错
        executor.setTaskDecorator(runnable -> {
            // 获取当前请求上下文（可能为 null，比如在非 Web 环境或启动阶段）
            RequestAttributes context = RequestContextHolder.getRequestAttributes();
            return () -> {
                try {
                    // 如果有上下文，就在异步线程中绑定它
                    if (context != null) {
                        RequestContextHolder.setRequestAttributes(context, true);
                    }
                    runnable.run(); // 执行原任务
                } finally {
                    // 清理上下文，避免内存泄漏
                    RequestContextHolder.resetRequestAttributes();
                }
            };
        });

        // 初始化线程池（必须调用）
        executor.initialize();

        // 返回的是 ExecutorService 接口
        return executor.getThreadPoolExecutor();
    }
}